package test;

import java.nio.ByteBuffer;

/**
 * Created by IntelliJ IDEA.
 * User: luotao
 * Date: 12-5-29
 * Time: 13:27
 */
public final class Messagex {
    private transient int mesgsize;
    private transient int position;
    private transient ByteBuffer body;
    private transient boolean isrelease;
    //private transient LinkChannel channel;

    public Messagex() {
        reset();
    }

    public Messagex reused() {
        mesgsize = 0;
        //  setProperty(MHead.MSGTYPE, 1);
        position = 0;
        body.position(position);
        return this;
    }


    public Messagex reset() {
        //   channel=null;
        isrelease = true;
        mesgsize = 0;
        body = ByteBuffer.allocate(1024);
        position = 0;
        body.position(position);
        return this;
    }

//  public void release(){
//    MessagePool.release(this);
//  }

    public boolean isusing() {
        return this.isrelease;
    }

    public Messagex using() {
        this.isrelease = false;
        return this;
    }

//  public Messagex reused(){
//    mesgsize=0;
//    setProperty(MHead.MSGTYPE,1);
//    position=GlobalDefine.MESG_HEAD;
//    body.position(position);
//    return this;
//  }

//  public Messagex setChannel(LinkChannel channel){
//    this.channel=channel;
//    return this;
//  }
//
//  public LinkChannel getChannel(){
//    return this.channel;
//  }
//
//  public <E>Messagex setProperty(MHead pkey,E val){
//    Class<?> type=pkey.Type();
//    if(type.equals(Byte.class)){
//      this.write((Integer)val,pkey.Offset(),false);
//    }
//    else if(type.equals(Short.class)){
//      this.writeShort((Integer)val,pkey.Offset(),false);
//    }
//    else if(type.equals(Integer.class)){
//      this.writeInt((Integer)val,pkey.Offset(),false);
//    }
//    else if(type.equals(Long.class)){
//      this.writeLong((Long)val,pkey.Offset(),false);
//    }
//    return this;
//  }
//
//  public <E>E getProperty(MHead pkey){
//    Class<?> type=pkey.Type();
//    if(type.equals(Byte.class)){
//      return (E)((Integer)read(pkey.Offset(),false));
//    }
//    else if(type.equals(Short.class)){
//      return (E)((Integer)readShort(pkey.Offset(),false));
//    }
//    else if(type.equals(Integer.class)){
//      return (E)((Integer)readInt(pkey.Offset(),false));
//    }
//    else if(type.equals(Long.class)){
//      return (E)((Long)readLong(pkey.Offset(),false));
//    }
//    return (E)this;
//  }

    public int getMesgSize() {
        return mesgsize == 0 ? position : mesgsize;
    }

//  public byte[] buildMessage(){
//    setProperty(MHead.SENDTIME,TimeUtil.to2000Time());
//    setProperty(MHead.TIMEOUT,TimeUtil.to2000Time()+20);
//    return body.array();
//  }

//  public Messagex parseMessage(byte[] bytes,int off,int len){
//    this.mesgsize=len;
//    body.position(0);
//    body.put(bytes,off,len);
//    body.position(position);
//    setProperty(MHead.RECVTIME,TimeUtil.to2000Time());
//    return this;
//  }

    public Messagex write(int val) {
        return write(val, body.position(), true);
    }

    private Messagex write(int val, int off, boolean lenchange) {
        position = body.position();
        body.position(off);
        body.put((byte) val);
        if (lenchange) {
            position = body.position();
        } else {
            body.position(position);
        }
        return this;
    }

    public Messagex writeShort(int val) {
        return writeShort(val, body.position(), true);
    }

    private Messagex writeShort(int val, int off, boolean lenchange) {
        position = body.position();
        body.position(off);
        body.putShort((short) val);
        if (lenchange) {
            position = body.position();
        } else {
            body.position(position);
        }
        return this;
    }

    public Messagex writeInt(int val) {
        return writeInt(val, body.position(), true);
    }

    private Messagex writeInt(int val, int off, boolean lenchange) {
        position = body.position();
        body.position(off);
        body.putInt(val);
        if (lenchange) {
            position = body.position();
        } else {
            body.position(position);
        }
        return this;
    }

    public Messagex writeLong(long val) {
        return writeLong(val, body.position(), true);
    }

    private Messagex writeLong(long val, int off, boolean lenchange) {
        position = body.position();
        body.position(off);
        body.putLong(val);
        if (lenchange) {
            position = body.position();
        } else {
            body.position(position);
        }
        return this;
    }

    public Messagex writeBytes(byte[] val) {
        return writeBytes(val, 0, val.length);
    }

    private Messagex writeBytes(byte[] val, int off, int len) {
        body.putInt((short) len);
        body.put(val, off, len);
        position = body.position();
        return this;
    }

    public Messagex writeFixString(String val, int len) {
        byte[] bytes = val.getBytes();
        int rlen = Math.min(bytes.length, len);
        body.put(bytes, 0, rlen);
        body.put(new byte[len - rlen]);
        position = body.position();
        return this;
    }

    public Messagex writeVarString(String val) {
        return writeVarString(val, Integer.MAX_VALUE);
    }

    public Messagex writeVarString(String val, int maxlen) {
        byte[] bytes = val.getBytes();
        int rlen = Math.min(bytes.length, maxlen);
        body.putInt(rlen);
        body.put(bytes, 0, rlen);
        position = body.position();
        return this;
    }

    public int read() {
        return read(body.position(), true);
    }

    private int read(int off, boolean lenchange) {
        position = body.position();
        body.position(off);
        int val = body.get();
        if (lenchange) {
            position = body.position();
        } else {
            body.position(position);
        }
        return val;
    }

    public int readShort() {
        return readShort(body.position(), true);
    }

    private int readShort(int off, boolean lenchange) {
        position = body.position();
        body.position(off);
        int val = body.getShort();
        if (lenchange) {
            position = body.position();
        } else {
            body.position(position);
        }
        return val;
    }

    public int readInt() {
        return readInt(body.position(), true);
    }

    private int readInt(int off, boolean lenchange) {
        position = body.position();
        body.position(off);
        int val = body.getInt();
        if (lenchange) {
            position = body.position();
        } else {
            body.position(position);
        }
        return val;
    }

    public long readLong() {
        return readLong(body.position(), true);
    }

    private long readLong(int off, boolean lenchange) {
        position = body.position();
        body.position(off);
        long val = body.getLong();
        if (lenchange) {
            position = body.position();
        } else {
            body.position(position);
        }
        return val;
    }

    public byte[] readBytes() {
        int rlen = body.getInt();
        byte[] val = new byte[rlen];
        body.get(val);
        position = body.position();
        return val;
    }


    public String readVarString() {
        return readVarString(Integer.MAX_VALUE);
    }

    public String readVarString(int maxlen) {
        int rlen = body.getInt();
        rlen = Math.min(rlen, maxlen);
        byte[] val = new byte[rlen];
        body.get(val);
        position = body.position();
        return new String(val);
    }

}